package com.vogue.meeting.fluent.dao.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.RandomUtil;
import com.vogue.meeting.common.context.UserContext;
import com.vogue.meeting.common.web.domain.Result;
import com.vogue.meeting.common.web.domain.ResultCode;
import com.vogue.meeting.fluent.dao.base.MeetingBaseDao;
import com.vogue.meeting.fluent.dao.intf.MeetingDao;
import com.vogue.meeting.fluent.entity.MeetingEntity;
import com.vogue.meeting.fluent.wrapper.MeetingQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * MeetingDaoImpl: 数据操作接口实现
 *
 * 这只是一个减少手工创建的模板文件
 * 可以任意添加方法和实现, 更改作者和重定义类名
 * <p/>@author Powered By Fluent Mybatis
 *
 *  RedisTemplate 常用方法汇总: https://blog.csdn.net/a1k2l45k/article/details/128396835
 *  Redis内存配置和淘汰策略(解决过期删除): https://www.jianshu.com/p/aa6e07532cbe
 */
@Repository
public class MeetingDaoImpl extends MeetingBaseDao implements MeetingDao {
    @Autowired
    private UserContext userContext;
    @Autowired
    private RedisTemplate<Serializable, String> redisTemplate;

    @Override
    public List<MeetingEntity> list(Integer page) {
        MeetingQuery query = new MeetingQuery();
        query.paged(page,10);
        List<MeetingEntity> meetings = mapper.listEntity(query);
        if (meetings.isEmpty())return new ArrayList<>();
        return meetings;
    }

    @Override
    public MeetingEntity create(MeetingEntity meeting) {
        String meetingCode = RandomUtil.randomString(8);
        meeting.setMeetingStatus("待开始");
        meeting.setMeetingCode(meetingCode);

        redisTemplate.opsForList().leftPushAll("meetingCode:"+meetingCode,new ArrayList<>());
        //过期设置
        redisTemplate.expire("meetingCode:"+meetingCode,1, TimeUnit.DAYS);

        mapper.save(meeting);
        return meeting;
    }

    @Override
    public Result enter(String meetingCode) {
        //TODO 先判断其是否在会议中
        MeetingQuery query = new MeetingQuery();
        query.where.meetingCode().eq(meetingCode).and.meetingStatus().eq("待开始").or.meetingStatus().eq("进行中");
        MeetingEntity meeting = mapper.findOne(query);
        if (meeting==null)return Result.failure(ResultCode.FAILURE);
        List<String> users = redisTemplate.opsForList().range("meetingCode:"+meetingCode,0,-1);
        if (users.contains(String.valueOf(userContext.getId()))){
            return Result.success(meeting);
        }
        users.add(String.valueOf(userContext.getId()));
        redisTemplate.expireAt("meetingCode:"+meetingCode, DateTime.now());
        return Result.success(meeting);
    }

    @Override
    public Result leave(String meetingCode) {
        //TODO 先判断其是否在会议中
        MeetingQuery query = new MeetingQuery();
        query.where.meetingCode().eq(meetingCode).and.meetingStatus().eq("进行中");
        MeetingEntity meeting = mapper.findOne(query);
        if (meeting==null)return Result.failure(ResultCode.FAILURE);
        // redisTemplate.opsForList().range(key, start, end);
        // 获取列表指定范围内的元素(start开始位置, 0是开始位置，end 结束位置, -1返回所有);
        List<String> users = redisTemplate.opsForList().range("meetingCode:"+meetingCode,0,-1);
        if (users.contains(String.valueOf(userContext.getId()))){
            // redisTemplate.opsForList().remove(key, index, value); 删除集合中值等于value的元素
            // index=0, 删除所有值等于value的元素;
            // index>0, 从头部开始删除第一个值等于value的元素;
            // index<0, 从尾部开始删除第一个值等于value的元素)；
            redisTemplate.opsForList().remove("meetingCode:"+meetingCode,0,String.valueOf(userContext.getId()));
            return Result.success(meeting);
        }
        return Result.success(meeting);
    }
}
